package de.ret_world.openrpgstudio.mapeditor;

import buoy.event.*;
import buoy.widget.BButton;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Adapter class for the MapEditor Tools and Brushes.
 *
 * @author Emu
 */
public class Tools {

    private TileSetWidget wTileSet;
    private MapEditorWidget editor;
    private HashMap<String, MapToolPlugin> toolPlugins;
    private Point startPoint;
    private MapToolPlugin active;
    private BButton activeBtn;

    protected Tools(TileSetWidget wTileSet, MapEditorWidget editor) {
        this.wTileSet = wTileSet;
        this.editor = editor;
        this.toolPlugins = new HashMap<>();
    }

    protected void registerTool(String tool, MapToolPlugin plugin) {
        toolPlugins.put(tool, plugin);
    }

    protected void unregisterTool(String tool) {
        toolPlugins.remove(tool);
    }

    protected void activatePlugin(CommandEvent ev) {
        if (active != null && activeBtn != null) {
            activeBtn.setText(active.inactiveText());
        }
        active = toolPlugins.get(ev.getActionCommand());
        activeBtn = (BButton) ev.getWidget();
        activeBtn.setText(active.activeText());
        active.activated();
    }

    protected void changeTSSelection(WidgetMouseEvent ev) {
        if (MouseEnteredEvent.class.isInstance(ev) || MouseExitedEvent.class.isInstance(ev) || MouseMovedEvent.class.isInstance(ev)) {
            return;
        }
        if (MouseClickedEvent.class.isInstance(ev)) {
            wTileSet.deselectTiles();
            wTileSet.selectTile(new Point(ev.getX(), ev.getY()));
        }
        if (MousePressedEvent.class.isInstance(ev)) {
            wTileSet.deselectTiles();
            startPoint = new Point(ev.getX(), ev.getY());
            wTileSet.selectTile(startPoint);
        }
        if (MouseReleasedEvent.class.isInstance(ev) || MouseDraggedEvent.class.isInstance(ev)) {
            wTileSet.deselectTiles();
            if (startPoint != null) {
                ArrayList<Point> points = new ArrayList<>();
                int sx = (int) startPoint.getX();
                int sy = (int) startPoint.getY();
                int nx = ev.getX();
                int ny = ev.getY();
                int dx = sx - nx;
                int dy = sy - ny;

                for (int x = 0; x <= Math.abs(dx); x++) {
                    for (int y = 0; y <= Math.abs(dy); y++) {
                        int px = sx, py = sy;
                        if (dx > 0) {
                            px -= x;
                        }
                        if (dx < 0) {
                            px += x;
                        }
                        if (dy > 0) {
                            py -= y;
                        }
                        if (dy < 0) {
                            py += y;
                        }
                        points.add(new Point(px, py));
                    }
                }

                for (Point p : points) {
                    wTileSet.selectTile(p);
                }
            }
        }
    }

    protected void clickedOnMap(WidgetMouseEvent ev) {
        if (MouseEnteredEvent.class.isInstance(ev)) {
            return;
        }
        if (MouseExitedEvent.class.isInstance(ev)) {
            editor.setPointer(-1, -1, -1);
        }
        if (MouseMovedEvent.class.isInstance(ev)) {
            if (active != null) {
                active.hover(ev.getX(), ev.getY());
            }
        }

        if (MousePressedEvent.class.isInstance(ev)) {
            if (active != null) {
                active.use(ev.getX(), ev.getY(), MapToolPlugin.STARTDRAG);
            }
        }
        if (MouseReleasedEvent.class.isInstance(ev) || MouseDraggedEvent.class.isInstance(ev)) {
            if (active != null) {
                active.use(ev.getX(), ev.getY(), MapToolPlugin.ENDDRAG);
            }
        }
        if (MouseClickedEvent.class.isInstance(ev)) {
            if (active != null) {
                active.use(ev.getX(), ev.getY(), MapToolPlugin.CLICKED);
            }
        }
    }
}
